﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Sofire.Data
{
    /// <summary>
    /// 表示一个执行查询的命令的基类。
    /// </summary>
    [Serializable]
    public abstract class ExecuteCommandBase : IDisposable, ICloneable
    {
        /// <summary>
        /// 设置或获取一个值，表示 <see cref="Sofire.Data.ExecuteCommandBase"/> 的默认的表名。默认为 “Table”。
        /// </summary>
        public static string DefaultTableName = "Table";
        /// <summary>
        /// 设置或获取一个值，表示 <see cref="Sofire.Data.ExecuteCommandBase"/> 的默认超时秒数。默认为 120 秒。
        /// <para>默认为 120 秒。如果设置为 0，则表示无限期的等待，但这并不是一个推荐的做法。</para>
        /// </summary>
        public static int DefaultTimeout = 120;

        /// <summary>
        /// 表示查询命令的 Transact-SQL 查询字符串。
        /// </summary>
        protected string _CommandText;
        /// <summary>
        /// 返回结果的 <see cref="System.Data.DataTable.TableName"/> 属性。在非 <see cref="System.Data.DataTable"/> 或 <see cref="System.Data.DataSet"/> 的查询时，将会忽略该属性配置。
        /// </summary>
        protected string _TableName = ExecuteCommandBase.DefaultTableName;
        /// <summary> 
        /// 在终止执行命令的尝试并生成错误之前的等待时间。
        /// </summary>
        protected int _Timeout = ExecuteCommandBase.DefaultTimeout;

        /// <summary>
        /// 是否已被释放。
        /// </summary>
        [NonSerialized]
        protected bool _isDisposed;
        [NonSerialized]
        private WeakReference _RuntimeObject;
        [NonSerialized]
        private object _Tag;


        /// <summary>
        /// 初始化 <see cref="Sofire.Data.ExecuteCommandBase"/> 的新实例。
        /// </summary>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        public ExecuteCommandBase(string commandText)
        {
            this._CommandText = commandText;
        }

        /// <summary>
        /// 析构方法。
        /// </summary>
        ~ExecuteCommandBase()
        {
            this.Dispose();
        }

        /// <summary>
        /// 设置或获取一个值，表示查询命令的 Transact-SQL 查询字符串。
        /// </summary>
        public string CommandText
        {
            get { return this._CommandText; }
            set { this._CommandText = value; }
        }

        /// <summary>
        /// 获取一个值，指示当前 <see cref="Sofire.Data.ExecuteCommand"/> 是否已释放。
        /// </summary>
        public bool IsDisposed
        {
            get { return this._isDisposed; }
        }

        /// <summary>
        /// 获取命令运行时的对象。
        /// </summary>
        public object RuntimeObject
        {
            get
            {
                if(this._RuntimeObject != null && this._RuntimeObject.IsAlive)
                    return this._RuntimeObject.Target;
                return null;
            }
        }

        /// <summary>
        /// 设置或获取一个值，表示返回结果的 <see cref="System.Data.DataTable.TableName"/> 属性。在非 <see cref="System.Data.DataTable"/> 或 <see cref="System.Data.DataSet"/> 的查询时，将会忽略该属性配置。
        /// <para>默认为 “Table”。</para>
        /// </summary>
        public string TableName
        {
            get { return this._TableName; }
            set { this._TableName = value; }
        }

        /// <summary>
        /// 设置或获取一个值，表示查询的一个标签。该值不参与序列化。
        /// </summary>
        public object Tag
        {
            get
            {
                return this._Tag;
            }
            set
            {
                this._Tag = value;
            }
        }

        /// <summary>
        /// 获取或设置一个值，表示在终止执行命令的尝试并生成错误之前的等待时间。
        /// <para>默认为 120 秒。如果设置为 0，则表示无限期的等待，但这并不是一个推荐的做法。</para>
        /// </summary>
        public int Timeout
        {
            get
            {
                return this._Timeout;
            }
            set
            {
                this._Timeout = value;
            }
        }

        /// <summary>
        /// 强制中断正在执行的命令。
        /// </summary>
        /// <returns>返回中断的结果。</returns>
        public abstract Result AbortExecuting();


        /// <summary>
        /// 创建作为当前实例副本的新对象。
        /// </summary>
        /// <returns>作为此实例副本的新对象。</returns>
        public abstract object Clone();

        /// <summary>
        /// 释放由 <see cref="Sofire.Data.ExecuteCommandBase"/> 使用的所有资源。
        /// </summary>
        public virtual void Dispose()
        {
            if(!this._isDisposed)
            {
                this._isDisposed = true;
                this._CommandText = null;
            }
        }

        /// <summary>
        /// 设置命令运行时的对象。
        /// </summary>
        /// <param name="runtimeObject">命令运行时的对象。</param>
        public virtual void SetRuntimeObject(object runtimeObject)
        {
            this._RuntimeObject = new WeakReference(runtimeObject);
        }

        /// <summary> 
        /// 返回当前查询命令的字符串形式（Transact-SQL 查询语句）。
        /// </summary>
        public override string ToString()
        {
            return this._CommandText;
        }

    }
}